package games.mapacman.server;

import games.mapacman.client.*;
import games.mapacman.common.Constants;
import games.mapacman.common.ZoneChangePoint;

import java.util.Map;
import java.util.Vector;
import marauroa.client.ClientFramework;

import marauroa.client.net.IPerceptionListener;
import marauroa.common.Log4J;
import marauroa.common.game.IRPZone;
import marauroa.common.game.RPObject;

class DummyAgentPerceptionListener implements IPerceptionListener {

    private static final marauroa.common.Logger logger = Log4J.getLogger(DummyAgentPerceptionListener.class);
    private Map<RPObject.ID, RPObject> wall_objects;
    private Vector<RPObject> ghosts;
    private Vector<RPObject> players;
    private ClientFramework clframework;

    public DummyAgentPerceptionListener(ClientFramework clframework, Map<RPObject.ID, RPObject> game_walls,
            Vector<RPObject> game_ghosts, Vector<RPObject> game_players) {
        wall_objects = game_walls;
        ghosts = game_ghosts;
        players = game_players;
        this.clframework = clframework;
    }

    public boolean onMyRPObject(RPObject added, RPObject deleted) {
        return false;
    }

    public boolean onAdded(RPObject object) {
        try {
            logger.debug("MaPacman::MaPacmanPerceptionListener::onAdded Object("
                    + object.getID() + ") added");

            if (object.get("type").equals(Constants.TYPE_GHOST)) {
                //object.put("move", 0);
                //object.put("imgCounter", 0);
                ghosts.add(object);
                MaPacmanRPWorld.get().addGhost(object);

            } else if (object.get("type").equals(Constants.TYPE_DOT)
                    || object.get("type").equals(Constants.TYPE_SUPERDOT)
                    || object.get("type").equals(Constants.TYPE_FRUIT)
                    || object.get("type").equals(Constants.TYPE_POWERPILL)) {
                //screen.addDot(object);

		for (IRPZone RPzone : MaPacmanRPWorld.get()) {
			MaPacmanZone zone = (MaPacmanZone) RPzone;
			if (zone.getName().equals(object.get("zoneid"))) {
				zone.addDot(object);
			}
		}

            } else if (object.get("type").equals(Constants.TYPE_PLAYER)) {
                //object.put("move", 0);
                //object.put("imgCounter", 0);
                players.add(object);
                MaPacmanRPWorld.get().addPlayer(object);
//				if (object.get("name").equals(screen.getPlayerName())) {
//					//screen.setPlayer(object);
//				}
                if (object.has("text") && (object.get("text").length() > 0)) {
//					GUI.printText(object.get("name") + " : "
//							+ object.get("text"));
                }
            } else if (object.get("type").equals(Constants.TYPE_WALL)) {
//                if (!wall_objects.containsValue(object)) {
//                    //wall_objects.put(object.getID(), object);
////					screen.addWall(object.getInt("x"), object.getInt("y"));
////					screen.drawWall(object);
//                }

                for (IRPZone RPzone : MaPacmanRPWorld.get()) {
			MaPacmanZone zone = (MaPacmanZone) RPzone;
			if (zone.getName().equals(object.get("zoneid"))) {
				zone.addWall(object);
			}
		}

            } else if (object.get("type").equals(Constants.TYPE_ZONECHANGE)) {
//				screen.addZoneChange(new ZoneChangePoint(object));

                for (IRPZone RPzone : MaPacmanRPWorld.get()) {
			MaPacmanZone zone = (MaPacmanZone) RPzone;
			if (zone.getName().equals(object.get("zoneid"))) {
				zone.addZoneChange(object);
			}
		}

            } else if (object.get("type").equals(Constants.TYPE_EATENSIGN) || object.get("type").equals(Constants.TYPE_SCORESIGN)) {
//				screen.addEatenSign(object);

                for (IRPZone RPzone : MaPacmanRPWorld.get()) {
			MaPacmanZone zone = (MaPacmanZone) RPzone;
			if (zone.getName().equals(object.get("zoneid"))) {
				zone.addSigns(object);
			}
		}

            } //else if (object.get("type").equals(Constants.TYPE_SCORESIGN)) {
////				screen.addScoreSign(object);
//            }
        } catch (Exception e) {
            logger.warn("MaPacman::MaPacmanPerceptionListener::onAdded " + object);
        }
        return false;
    }

    public boolean onModifiedAdded(RPObject object, RPObject changes) {
        // NOTE: We do handle the perception here ourselves. See that we return
        // true
        try {
            logger.debug("MaPacman::MaPacmanPerceptionListener::onModifiedAdded Object("
                    + object.getID()
                    + ") modified in Game Objects container");

            object.applyDifferences(changes, null);

            if (object.get("type").equals(Constants.TYPE_GHOST)) {
                object.put("move", 0);
                MaPacmanRPWorld.get().modify(object);
            } else if (object.get("type").equals(Constants.TYPE_DOT)
                    || object.get("type").equals(Constants.TYPE_SUPERDOT)
                    || object.get("type").equals(Constants.TYPE_FRUIT)
                    || object.get("type").equals(Constants.TYPE_POWERPILL)) {
//				screen.addDot(object);
                for (IRPZone RPzone : MaPacmanRPWorld.get()) {
			MaPacmanZone zone = (MaPacmanZone) RPzone;
			if (zone.getName().equals(object.get("zoneid"))) {
				zone.updateDot(object);
			}
		}

            } else if (object.get("type").equals(Constants.TYPE_PLAYER)) {
                // if (object.getInt("power")>0)
                // System.out.println("powermode");
                object.put("move", 0);
                if (object.has("text") && (object.get("text").length() > 0)) {
//					GUI.printText(object.get("name") + " : "
//							+ object.get("text"));
					/*
                     * if (!changes.get("zoneid").equals(object.get("zoneid")))
                     * players.remove(object);
                     */
                }
                MaPacmanRPWorld.get().modify(object);
            } else if (object.get("type").equals(Constants.TYPE_WALL)) {
            }
            
        } catch (Exception e) {
            logger.debug("MaPacman::MaPacmanPerceptionListener::onModifiedAdded "
                    + changes.toString());
            logger.warn("MaPacman::MaPacmanPerceptionListener::onModifiedAdded "
                    + e);
        }
        return true;
    }

    public boolean onModifiedDeleted(RPObject object, RPObject changes) {
        return false;
    }

    public boolean onDeleted(RPObject object) {
        try {
            logger.debug("MaPacman::MaPacmanPerceptionListener::onDeleted Object("
                    + object
                    + ") removed from Static Objects container");

            if(object.get("type")==null){
                MaPacmanRPWorld.get().remove(object.getID());
                return false;
            }
            if (object.get("type").equals(Constants.TYPE_PLAYER)) {
                for (RPObject player : players) {
                    //if (player.get("name").equals(object.get("name"))) {
                    if (player.get("id").equals(object.get("id"))) {
                        players.remove(player);
                        MaPacmanRPWorld.get().removePlayer(object.getID());
                        return false;
                    }
                }
            } else if (object.get("type").equals(Constants.TYPE_EATENSIGN)) {
                // screen.removeEatenSign(object);
                MaPacmanRPWorld.get().remove(object.getID());
                for (IRPZone RPzone : MaPacmanRPWorld.get()) {
                    MaPacmanZone zone = (MaPacmanZone) RPzone;
                    if (zone.getName().equals(object.get("zoneid"))) {
                        zone.removeSigns(object);
                        return false;
                    }
		}
            } else if (object.get("type").equals(Constants.TYPE_GHOST)) {
                for (RPObject ghost : ghosts) {
                    if (ghost.get("id").equals(object.get("id"))) {
                        ghosts.remove(ghost);
                        MaPacmanRPWorld.get().removeGhost(object.getID());
                        return false;
                    }
                }

            } else if (object.get("type").equals(Constants.TYPE_DOT)) {
                
            } else if (object.get("type").equals(Constants.TYPE_WALL)) {
            }
            
        } catch (Exception e) {
            logger.warn(object+ object.get("type") + " MaPacman::MaPacmanPerceptionListener::onDeleted"+e);
        }
        return false;
    }

    public void onSynced() {
        sendSyncMsg();
        logger.debug("MaPacman::MaPacmanPerceptionListener::onSynced Synced with server state.");
    }

    public void onUnsynced() {
        //sendSyncMsg();
        logger.debug("MaPacman::MaPacmanPerceptionListener::onUnsynced Request resync");
        // resync();
    }

    public void onException(Exception e,
            marauroa.common.net.message.MessageS2CPerception perception) {
        logger.debug("MaPacman::MaPacmanPerceptionListener::onException "
                + perception.toString());
        logger.warn("MaPacman::MaPacmanPerceptionListener::onException " + e);
        e.printStackTrace();
        System.exit(-1);
    }

    public boolean onClear() {
        logger.debug("MaPacman::MaPacmanPerceptionListener::onClear Clear!");
        return false;
    }

    public void onPerceptionBegin(byte type, int timestamp) {
        /*
         * logger.debug("MaPacman::MaPacmanPerceptionListener::onPerceptionBegin Params: "
         * + type + ", " + timestamp);
         */
    }

    public void onPerceptionEnd(byte type, int timestamp) {
        /*
         * logger.debug("MaPacman::MaPacmanPerceptionListener::onPerceptionEnd Params: "
         * + type + ", " + timestamp);
         */
    }

    public void sendSyncMsg() {
        this.clframework.sendSyncConfirmS2S();
    }
}
